package com.doctor.comm;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import com.doctor.net.NetUtil;
import com.google.gson.Gson;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.StatFs;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.widget.Toast;

public class FileHelper {
	
	
	/**
	 * 根据包名判断软件是否已安装
	 * @param context
	 * @param packageName
	 * @return
	 */
	public static boolean isPkgInstalled(Context context, String packageName){
		PackageManager pm=context.getPackageManager();
		try {
			pm.getPackageInfo(packageName, 0);
		} catch (NameNotFoundException e) {
			return false;
		}
		return true;
	}
	
	/**
	 * 启动软件
	 * @param context
	 * @param activity
	 * @param packageName 包名
	 * @param startActivityName 启动界面
	 * @param notInstalledTip 未安装提示
	 */
	public static void startSoftware(Context context, Activity activity, String packageName, String startActivityName,
		 String notInstalledTip){
		if (isPkgInstalled(context, packageName)) {
			Intent intent=new Intent();
			ComponentName componentName=new ComponentName(packageName, startActivityName);
			intent.setComponent(componentName);
			//启动程序
			activity.startActivity(intent);
			LoadingTip.hideDialog();
		} else {
			Toast.makeText(activity, notInstalledTip, Toast.LENGTH_SHORT).show();
		}
	}
	
	
	
	/**
	 * 根据uri获取文件输入流
	 * @param activity
	 * @param uri
	 * @return
	 */
	public static InputStream getInputStreamFromUri (Activity activity,Uri uri){
		InputStream in = null;
	    try {
		    if (uri.getScheme() == null) {
				// 绝对路径
				File file = new File(uri.toString());
				in = new FileInputStream(file);
			} else if (uri.getScheme().equalsIgnoreCase("content") || 
					uri.getScheme().equalsIgnoreCase("file")) {
				// content://xxx或file://xxx格式的本地uri
				in = activity.getContentResolver().openInputStream(uri);
			}
		} catch (IOException e){
	    	e.printStackTrace();
	    } 
	    return in;
	}
	
	
	public static void writeDataToFile(final String netPath, final String path){	
		new Thread(){
			public void run() {
				try {
					File f=new File(path);
					if (!f.exists()) {
						f.createNewFile();
					}
					
					BufferedWriter writer=new BufferedWriter(new FileWriter(f));
					writer.write(netPath);
					writer.flush();
					writer.close();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO: handle exception
				}
			}
		}.start();
	}
	
	public interface ResourceCallback{
		public void onGetDone(Object obj);
	}
	/**
	 * 从资源文件读取文本 数据
	 * @param context
	 * @param resource
	 * @param bean
	 * @param callback
	 */
	public static <T> void getBeansByResource(final Context context, final int resource ,final Class<T> bean, final ResourceCallback callback){
		new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					BufferedReader reader=new BufferedReader(new InputStreamReader(context.getResources().openRawResource(resource),"GBK"));
					String str="";
					StringBuilder builder= new StringBuilder();
					while ((str=reader.readLine())!=null) {
						builder.append(str);
					}
					String data=builder.toString().trim();
					Gson gson=new Gson();
					Object obj= gson.fromJson(data, bean);
					
					callback.onGetDone(obj);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
	}
	
	/**
	 * 从资源文件读取文本 数据
	 * @param context
	 * @param resource
	 * @param bean
	 * @param callback
	 */
	public static <T> void getBeansByResource2(final Context context, final int resource ,final Class<T> bean, final ResourceCallback callback){
		Handler handler=new Handler();
		handler.post(new Runnable() {		
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					BufferedReader reader=new BufferedReader(new InputStreamReader(context.getResources().openRawResource(resource)));
					String str="";
					StringBuilder builder= new StringBuilder();
					while ((str=reader.readLine())!=null) {
						builder.append(str);
					}
					String data=builder.toString().trim();
					Gson gson=new Gson();
					Object obj= gson.fromJson(data, bean);
					
					callback.onGetDone(obj);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
	
	
//	/**
//	 * 根据uri返回文件路径
//	 * @param context
//	 * @param uri
//	 * @return
//	 */
//	 public static String uri2Path(Context context,Uri uri){
//		 
//	     String uriString=uri.toString();
//	     if (uriString.startsWith("content")) {
//			//没有文件后缀
//	    	 String imgPath = null;
//	        Cursor cursor = context.getContentResolver().query(uri, new String[]{ MediaStore.Images.Media.DATA }, null, null, null);
//	        if (cursor!=null && cursor.getCount()>0) {
//				int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
//				cursor.moveToFirst(); 
//				imgPath = cursor.getString(columnIndex);
//			}
//	        cursor.close();
//	        return imgPath;
//		} else if (uriString.startsWith("file")) {
//			return uriString;
//		}
//	     return null;
//	 }
	 
	 
	 /**
		 * 根据uri的规则返回合适的路径Uri，以便能正确从本地读取路径。
		 * 从Android 4.4开始，从相册选取的图片得到的路径格式变成：content://com.android.providers.media.documents/document/image:3951
		 * 这种Uri是无法直接用于裁剪的，因为不是本地图片路径，该方法正是为了解决此问题，根据Uri的形式得到本地图片正确的路径。
		 * @param context
		 * @param uri
		 * @return
		 */
		public static String uri2Path(final Context context, final Uri uri) {
			if(uri == null) {
				return null;
			}
			String path = null;
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
				path = getPathAfter19(context, uri);
			}
			if (path == null || path.trim().length() <= 0) {
				path = getPathBefore19(context, uri);
			}
			
			return path;
		}
		
		/**
		 * 获取Android 4.4版本以前的选择图片Uri。
		 * @param context
		 * @param uri 选取图片后的intent.getData
		 * @return 本地图片的Uri
		 */
		private static String getPathBefore19(final Context context, final Uri uri) {
			if(uri != null){			
				String uriStr = uri.toString();
				String path = uriStr.substring(10,uriStr.length());
				if(path.startsWith("com.sec.android.gallery3d")){
					return null;
				}
			}		
			String[] filePathColumn = { MediaStore.Images.Media.DATA };
			String picturePath = null;
			Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null);
			
			if (cursor != null) {
				cursor.moveToFirst();
				int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
				picturePath = cursor.getString(columnIndex);
				cursor.close();
			} else if ("file".equalsIgnoreCase(uri.getScheme())) {
				return uri.getPath();
			}
			
			if(TextUtils.isEmpty(picturePath)) {
				return null;
			}
			return picturePath;	
			
		}//end getUriBefore19
	 
	 
		/**
		 * 根据uri的规则返回合适的路径，以便能从本地得到图片(apilevel>=19)。
		 * @param context
		 * @param uri
		 * @return
		 */
		@TargetApi(Build.VERSION_CODES.KITKAT)
		@SuppressLint("NewApi")
		private static String getPathAfter19(final Context context, final Uri uri) {

			final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

			// DocumentProvider
			if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
				// ExternalStorageProvider
				if (isExternalStorageDocument(uri)) {
					final String docId = DocumentsContract.getDocumentId(uri);
					final String[] split = docId.split(":");
					final String type = split[0];

					if ("primary".equalsIgnoreCase(type)) {
						return Environment.getExternalStorageDirectory() + "/"
								+ split[1];
					}

					// TODO handle non-primary volumes
				}
				// DownloadsProvider
				else if (isDownloadsDocument(uri)) {

					final String id = DocumentsContract.getDocumentId(uri);
					final Uri contentUri = ContentUris.withAppendedId(
							Uri.parse("content://downloads/public_downloads"),
							Long.valueOf(id));

					return getDataColumn(context, contentUri, null, null);
				}
				// MediaProvider
				else if (isMediaDocument(uri)) {
					final String docId = DocumentsContract.getDocumentId(uri);
					final String[] split = docId.split(":");
					final String type = split[0];

					Uri contentUri = null;
					if ("image".equals(type)) {
						contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
					} else if ("video".equals(type)) {
						contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
					} else if ("audio".equals(type)) {
						contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
					}

					final String selection = "_id=?";
					final String[] selectionArgs = new String[] { split[1] };

					return getDataColumn(context, contentUri, selection,
							selectionArgs);
				}
			}
			// MediaStore (and general)
			else if ("content".equalsIgnoreCase(uri.getScheme())) {

				// Return the remote address
				if (isGooglePhotosUri(uri))
					return uri.getLastPathSegment();

				return getDataColumn(context, uri, null, null);
			}
			// File
			else if ("file".equalsIgnoreCase(uri.getScheme())) {
				return uri.getPath();
			}

			return null;
		}

		/**
		 * Get the value of the data column for this Uri. This is useful for
		 * MediaStore Uris, and other file-based ContentProviders.
		 *
		 * @param context
		 *            The context.
		 * @param uri
		 *            The Uri to query.
		 * @param selection
		 *            (Optional) Filter used in the query.
		 * @param selectionArgs
		 *            (Optional) Selection arguments used in the query.
		 * @return The value of the _data column, which is typically a file path.
		 */
		private static String getDataColumn(Context context, Uri uri,
				String selection, String[] selectionArgs) {

			Cursor cursor = null;
			final String column = "_data";
			final String[] projection = { column };

			try {
				cursor = context.getContentResolver().query(uri, projection,
						selection, selectionArgs, null);
				if (cursor != null && cursor.moveToFirst()) {
					final int index = cursor.getColumnIndexOrThrow(column);
					return cursor.getString(index);
				}
			} finally {
				if (cursor != null)
					cursor.close();
			}
			return null;
		}

		/**
		 * @param uri
		 *            The Uri to check.
		 * @return Whether the Uri authority is ExternalStorageProvider.
		 */
		private static boolean isExternalStorageDocument(Uri uri) {
			return "com.android.externalstorage.documents".equals(uri
					.getAuthority());
		}

		/**
		 * @param uri
		 *            The Uri to check.
		 * @return Whether the Uri authority is DownloadsProvider.
		 */
		private static boolean isDownloadsDocument(Uri uri) {
			return "com.android.providers.downloads.documents".equals(uri
					.getAuthority());
		}

		/**
		 * @param uri
		 *            The Uri to check.
		 * @return Whether the Uri authority is MediaProvider.
		 */
		private static boolean isMediaDocument(Uri uri) {
			return "com.android.providers.media.documents".equals(uri
					.getAuthority());
		}

		/**
		 * @param uri
		 *            The Uri to check.
		 * @return Whether the Uri authority is Google Photos.
		 */
		private static boolean isGooglePhotosUri(Uri uri) {
			return "com.google.android.apps.photos.content".equals(uri
					.getAuthority());
		}
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	
	 /**
	  * 拨打电话
	  * @param activity
	  * @param context
	  * @param phoneNumber
	  */
	 public static void dialPhone(Activity activity,Context context,String phoneNumber){
		 TelephonyManager telManager=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);			
			if (telManager.getSimState()==TelephonyManager.SIM_STATE_ABSENT) {
				Toast.makeText(context, "未插入SIM卡！", Toast.LENGTH_SHORT).show();
			} else if (telManager.getSimState()==TelephonyManager.SIM_STATE_READY) {
				if (null!=phoneNumber && !"".equals(phoneNumber)) {
					activity.startActivity(new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phoneNumber)));
				} else {
					Toast.makeText(context, "未填写手机和电话！", Toast.LENGTH_SHORT).show();
				}
			} else {
				Toast.makeText(context, "请确保SIM卡状态良好！", Toast.LENGTH_SHORT).show();
			}		 
	 }
	 
	 
	 /**
	  * 拨打电话
	  * @param activity
	  * @param context
	  * @param phoneNumber
	  * @param tip 未设置号码的提示信息
	  */
	 public static void dialPhone(Activity activity,Context context,String phoneNumber,String tip){
		 TelephonyManager telManager=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);			
			if (telManager.getSimState()==TelephonyManager.SIM_STATE_ABSENT) {
				Toast.makeText(context, "未插入SIM卡！", Toast.LENGTH_SHORT).show();
			} else if (telManager.getSimState()==TelephonyManager.SIM_STATE_READY) {
				if (null!=phoneNumber && !"".equals(phoneNumber)) {
					activity.startActivity(new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phoneNumber)));
				} else {
					Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
				}
			} else {
				Toast.makeText(context, "请确保SIM卡状态良好！", Toast.LENGTH_SHORT).show();
			}		 
	 }
	 
	 
	 /**
	  * 从网络下载视频文件到本地保存
	  * @param remoteUrl
	  * @param localUrl
	  * @return 是否下载完成
	  */
	 public static boolean downVideo(String remoteUrl, String localUrl){
		 if (!NetUtil.hasNetwork(MyApplication.getInstance())) {
			return false;
		}
		 
		 File cacheFile = new File(localUrl);
		 FileOutputStream out = null;
			InputStream is = null;
			boolean result = false;
			try {
				URL url = new URL(remoteUrl);
				HttpURLConnection httpConnection = (HttpURLConnection) url
						.openConnection();

				if (!cacheFile.exists()) {
					cacheFile.getParentFile().mkdirs();
					cacheFile.createNewFile();
				}
				
				long readSize = cacheFile.length();
				out = new FileOutputStream(cacheFile, true);

				httpConnection.setRequestProperty("User-Agent", "NetFox");
				httpConnection.setRequestProperty("RANGE", "bytes="
						+ readSize + "-");
				is = httpConnection.getInputStream();
				int mediaLength = is.available();
				
				if (getAvailableSize() <= mediaLength) {
					//存储空间不够
					result = false;
					return result;
				}
				
				if (mediaLength == -1) {
					result = false;
					return result;
				}

				byte buf[] = new byte[4 * 1024];
				int size = 0;
				int downLoadedLength = 0;  //已经下载的字节数

				while ((size = is.read(buf)) != -1) {
					downLoadedLength += size;
					try {
						out.write(buf, 0, size);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				out.flush();
				
				if (downLoadedLength < mediaLength) {
					result = false;
					return result;
				}
				
				result = true;
				
			} catch (Exception e) {
				e.printStackTrace();
				result = false;
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						//
					}
				}

				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						//
					}
				}
				
				if (!result && cacheFile.exists()) {
					//视频未下载完成，将其不完整的文件删除
					cacheFile.delete();
				}
			}
			
			return result;
	 }
	 
	 
		/**
	     * 计算sd卡的剩余大小
	     * @return byte
	     */
	    public static long getAvailableSize() {
	    	File file = new File(ConstConfig.getInerCardPath());
	    	if (!file.exists()) {
				return 0L;
			}
	    	StatFs statFs = new StatFs(file.getPath());
	    	
	    	//获得Sdcard上每个block的size
	        long blockSize = statFs.getBlockSize();
	        //获取可供程序使用的Block数量
	        long blockavailable = statFs.getAvailableBlocks();
	        //计算标准大小使用：1024，当然使用1000也可以
	        long blockavailableTotal = blockSize * blockavailable;
	        return blockavailableTotal;
	    }
	 
	 
//	 //获取设备id
//	 public static String getImieStatus(Context context) {
//		//tm.getDeviceId()表示唯一的设备ID，例如对于GSM手机返回IMEI，对于CDMA手机返回MEID,如果设备不可用则返回NULL，比如在模拟器上。
//		//手机串号
//		TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
//		String deviceId = tm.getDeviceId();
//		//网卡地址
//		WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//		WifiInfo info = wifi.getConnectionInfo();
//		String str_mac = info.getMacAddress(); 
//		if(deviceId != null){
//			if(!"000000000000000".equals(deviceId) && !"0000000000000".equals(deviceId)){
//				return deviceId;
//			}
//		}else if (str_mac!=null) {
//			return str_mac;
//		}
//		return "emulator";
//	}
	
	 
	 
		/**
		 * 获取设备唯一id(2016/06/23修改添加)
		 * 优先获取deviceId,失败则获取网卡地址
		 * @param context
		 * @return
		 */
		public static String getImieStatus(Context context) {
			String serialNumber = getDeviceId(context);
			if (serialNumber == null) {
				serialNumber = getMacAddress(context);
			}
			return serialNumber == null ? "emulator" : serialNumber;
		}
		
		
		/**
		 * 获取设备id(只适用于有通话功能的设备)
		 * @param context
		 * @return
		 */
		private static String getDeviceId(Context context) {
			String deviceId = null;
			if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
				return deviceId;
			}
			
			TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			if (manager != null) {
				deviceId = manager.getDeviceId();
			}
			
			if (deviceId == null || deviceId.length() == 0) {
				deviceId = null;
			} else {
				for (int i = 0; i < deviceId.length(); i++) {
					String single = deviceId.substring(i, i+1);
					if (!"0".equals(single) && !"".equals(single)) {
						break;
					} else if (i == deviceId.length() - 1) {
						//从第1个至最后1个都是0或空字符
						deviceId = null;
					}
				}
			}
			return deviceId;
		}	
		
		
		
		/**
		 * 获取wifi地址
		 * @param context
		 * @return
		 */
		private static String getMacAddress(Context context) {
			String serial = null;
			WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
			if (manager != null) {
				serial = manager.getConnectionInfo().getMacAddress();
			}
			return serial;
		}	 
	 
	 
	 
	 
	 
}
